---
title: SQL 函数
description: 函数可以把我们经常使用的代码封装起来，需要的时候直接调用即可。
---
## 什么是 SQL 函数
函数可以将我们经常使用的代码封装起来，需要的时候直接调用即可。

SQL 中的函数一般是在数据上执行的，可以很方便的转换和处理数据，得到更有意义的结果，比如返回指定条件的函数，或者求某个字段的平均值等。

## 常见的 SQL 函数
SQL 提供了一些常用的内置函数，也可以自定义自己的函数。SQL 内置函数对于不同的数据库软件来说具有一定的通用性，我们可以把内置函数分为四类：
1. 算数函数
2. 字符串函数
3. 日期函数
4. 转换函数

它们是 SQL 函数常用的划分标准。

函数是对提取出来的数据进行操作，那么数据表中字段类型的定义有哪几种呢？

不管是整数类型、还是浮点类型，实际上对应的就是数值类型。

文本内容都是字符串类型。

此外还需要保存时间，也就是日期类型。

那么针对数值、字符串和日期类型的数据，我们可以对他分别进行算数函数、字符串函数以及日期函数的操作。如果想要完成不同类型数据之间的转换，就可以使用转换函数。

## 算数函数
算数函数，顾名思义就是对数值类型的字段进行算数运算。常用的算数函数及含义如下表所示：

| 函数名  | 定义                                                         |
| ------- | ------------------------------------------------------------ |
| ABS()   | 取绝对值                                                     |
| MOD()   | 取余                                                         |
| ROUND() | 四舍五入为指定的小数位数，需要有两个参数，分别为字段名称，小数位数。 |

```sql title='例子'
mysql> SELECT ABS(-2);
+---------+
| ABS(-2) |
+---------+
|       2 |
+---------+
1 row in set (0.00 sec)

mysql> SELECT MOD(15,2);
+-----------+
| MOD(15,2) |
+-----------+
|         1 |
+-----------+
1 row in set (0.00 sec)

mysql> SELECT ROUND(1.55,1);
+---------------+
| ROUND(1.55,1) |
+---------------+
|           1.6 |
+---------------+
1 row in set (0.00 sec)
```

## 字符串函数

常用的字符串函数包括了字符串拼接、大小写转换，求长度及字符串替换和截取等。

| 函数名        | 定义                                                         |
| ------------- | ------------------------------------------------------------ |
| CONCAT()      | 将多个字符串拼接起来                                         |
| LENGTH()      | 计算字段的长度，一个汉字算三个字符，一个数字或字母算一个字符 |
| CHAR_LENGTH() | 计算字段的长度，汉字、数字、字母都算一个字符                 |
| LOWER()       | 将字符串中的字符转化成小写                                   |
| UPPER()       | 将字符串中的字符转化成大写                                   |
| REPLACE()     | 替换函数，有三个参数，分别为：要替换的表达式或字段名、想要查找的被替换字符串、替换成那个字符串 |
| SUBSTRING()   | 截取字符串，有三个参数，分别为：带截取的表达式或字段名、开始截取的位置、想要截取的字符串长度 |

```sql title='例子'
mysql> SELECT REPLACE('fabcd','abc',123);
+----------------------------+
| REPLACE('fabcd','abc',123) |
+----------------------------+
| f123d                      |
+----------------------------+
1 row in set (0.00 sec)

mysql> SELECT SUBSTRING('fabcd',1,3);
+------------------------+
| SUBSTRING('fabcd',1,3) |
+------------------------+
| fab                    |
+------------------------+
1 row in set (0.00 sec)
```

## 日期函数

日期函数是对数据表中的日期进行处理，常用的函数包括：

| 函数名              | 定义                              |
| ------------------- | --------------------------------- |
| CURRENT_DATE()      | 系统当前日期                      |
| CURRENT_TIME()      | 系统当前时间，没有具体的日期      |
| CURRENT_TIMESTAMP() | 系统当前时间，包括具体的日期+时间 |
| EXTRACT()           | 抽取具体的年、月、日              |
| DATE()              | 返回时间的日期部分                |
| YEAR()              | 返回时间的年份部分                |
| MONTH()             | 返回时间的月份部分                |
| DAY()               | 返回时间的天数部分                |
| HOUR()              | 返回时间小时部分                  |
| MINUTE()            | 返回时间的分钟部分                |
| SECOND()            | 返回时间的秒部分                  |

```sql title='例子'
mysql> SELECT CURRENT_DATE();
+----------------+
| CURRENT_DATE() |
+----------------+
| 2023-02-22     |
+----------------+
1 row in set (0.00 sec)

mysql> SELECT CURRENT_TIME();
+----------------+
| CURRENT_TIME() |
+----------------+
| 23:42:38       |
+----------------+
1 row in set (0.00 sec)

mysql> SELECT CURRENT_TIMESTAMP();
+---------------------+
| CURRENT_TIMESTAMP() |
+---------------------+
| 2023-02-22 23:42:49 |
+---------------------+
1 row in set (0.00 sec)

mysql> SELECT EXTRACT(YEAR FROM '2021-02-22');
+---------------------------------+
| EXTRACT(YEAR FROM '2021-02-22') |
+---------------------------------+
|                            2021 |
+---------------------------------+
1 row in set (0.00 sec)

mysql> SELECT DATE('2020-02-22 12:00:03');
+-----------------------------+
| DATE('2020-02-22 12:00:03') |
+-----------------------------+
| 2020-02-22                  |
+-----------------------------+
1 row in set (0.00 sec)
```

注意：DATE 日期格式必须是 yyyy-mm-dd 的形式。如果要进行日期比较，就要使用 DATE 函数，不要直接使用日期与字符串进行比较。

## 转换函数

转换函数可以转换数据之间的类型，常用的函数如下表所示：

| 函数名    | 定义                                                         |
| --------- | ------------------------------------------------------------ |
| CAST()    | 数据类型转换，参数是一个表达式，表达式通过 AS 关键词分割了 2 个参数，分别是原始数据和目标数据类型。 |
| COALESC() | 返回第一个非空数值                                           |

```sql title='例子'
mysql> SELECT CAST(123.123 AS INT);
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'INT)' at line 1
mysql> SELECT CAST(123.123 AS DECIMAL(22,2));
+--------------------------------+
| CAST(123.123 AS DECIMAL(22,2)) |
+--------------------------------+
|                         123.12 |
+--------------------------------+
1 row in set (0.00 sec)

mysql> SELECT COALESCE(null,1,2);
+--------------------+
| COALESCE(null,1,2) |
+--------------------+
|                  1 |
+--------------------+
1 row in set (0.00 sec)
```

CAST函数在类型转换的时候，不会四舍五入，如果原数值有小数，那么转换为整数类型就会报错。不过可以指定转化的小数类型。

在 MySQL 和 SQL Server 中，可以用 DECIMAL(a,b)来指定，其中 a 代表整数部分和小数部分加起来最大的位数。

b代表小数位数 。



## 使用 SQL 函数会带来问题

1. 不同数据库，不同版本的函数存在差异
2. 使用函数会导致索引失效

